home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Utilities / Scion / ARexx / PrintPedigree.rexx < prev    next >
OS/2 REXX Batch file  |  1997-11-04  |  25KB  |  862 lines

  1. /****************************************************************************
  2.  *                                                                          *
  3.  * $VER: PrintPedigree 2.08 (25 Nov 1996)
  4.  *                                                                          *
  5.  *                      Written by Freddy Ariës                             *
  6.  * Address: Lindeboomweg 7, NL-7135 KE Harreveld, The Netherlands.          *
  7.  *                                                                          *
  8.  * Output options:                                                          *
  9.  *  1. Forefathers (male ancestor line only)       [Dutch: stamreeks]       *
  10.  *  2. Pedigree Chart; no siblings                 [Dutch: kwartierstaat]   *
  11.  *  3. Pedigree Chart; only siblings of proband  (= of youngest generation) *
  12.  *  4. Pedigree Chart; all siblings                                         *
  13.  *                                                                          *
  14.  * This script uses (by default) the rexxreqtools.library (which requires   *
  15.  * a version of reqtools larger than 2.0 and rexxsyslib.library)            *
  16.  * If you do not have these, run SetDefaults.rexx to change the settings.   *
  17.  *                                                                          *
  18.  * As of v2 of this script, and Scion V4, the current person on Scion's     *
  19.  * Personal Window will be used to determine where the search starts.       *
  20.  * Scion 3.13 can still be used, though, in which case the user will be     *
  21.  * asked at which IRN he wants to start.                                    *
  22.  *                                                                          *
  23.  * So why this PrintPedigree script when Scion already has print options    *
  24.  * for Ahnentafel/pedigree charts? Well, the reason is simple: the format   *
  25.  * of the Ahnentafel generated by Scion does not conform to the guidelines  *
  26.  * of the Dutch CBG (Central Bureau for Genealogy) and NGV (Nederlandse     *
  27.  * Genealogische Vereniging; Dutch Genealogical Society). So I created my   *
  28.  * own PrintPedigree script, that *does* follow their guidelines.           *
  29.  *                                                                          *
  30.  * DONE:                                                                    *
  31.  *  - Now uses preference file for default settings                         *
  32.  *  - count the number of lines output and give a formfeed after a          *
  33.  *    certain number (ie. skip page breaks)                                 *
  34.  *  - Inclusion of name/address data from prefs (optional)                  *
  35.  *                                                                          *
  36.  * TO DO (low priority, unless someone really wants this):                  *
  37.  *  - add a menu option for the maximum number of generations to print      *
  38.  *  - allow user to specify if he wants burial data, occupation, comments,  *
  39.  *    references fields, etc. printed                                       *
  40.  *  - option: include empty fields                                          *
  41.  *  - find a good way to handle sex-fields with value '?' (see below)       *
  42.  *  - include Scion v5 submitter data                                       *
  43.  *  - Suggestions, comments, bugreports, donations, etc. are appreciated.   *
  44.  *                                                                          *
  45.  * Known Bugs/Problems:                                                     *
  46.  *  - This script is dog slow for large databases (ie. more than, say, 10   *
  47.  *    generations), even on Amigas with a Turboboard!                       *
  48.  *  - Incorrect assumptions may be made (with regard to father/mother) when *
  49.  *    there are persons in the database whose sex-field has value '?'       *
  50.  *                                                                          *
  51.  ****************************************************************************/
  52.  
  53. options failat 20; options results
  54. arg prtin outname noirn mgen outval
  55.  
  56. versionstr = "2.08"
  57.  
  58. /* Don't change the settings here! Run SetDefaults.rexx instead! */
  59. usereq = 1; outp = 1; useirn = 1
  60. prtdev = stdout; prtopt = 0; scrdev = stdout
  61. plwidth = 78; pgsize = 0
  62. subf = 0; subm. = ""
  63. PSCR = 'SCIONGEN'
  64.  
  65. scrname = "CON:0//639//Scion_Output/AUTO/WAIT/CLOSE/SCREEN"
  66. prtrev = 0;    /* prtrev = 0 means youngest (first) generation = I */
  67.         /* prtrev = 1 means oldest (last) generation = I */
  68. DbtGen = 10;
  69.   /* Suggested value for 68000: 10, with Turbo-boards: 12
  70.    * From this generation onwards, every additional generation needs a confirm
  71.    * Note: 10 generations means (up to) 1024 persons,
  72.    * 12 generations means (up to) 4096 persons !!!
  73.    */
  74. pgline = 1
  75. NL = '0A'x
  76.  
  77. signal on IOERR
  78.  
  79. /* parse command line options, to allow calling the script automatically,
  80.  * eg. from a function key
  81.  */
  82.  
  83. do while prtin = '?'
  84.   Tell("NUMOPT/A/N,OUTFILE/A,NOIRN/S,MAXGEN/N,QUIET/S,NOREQ/S: ")
  85.   pull prtin outname noirn mgen outval
  86. end
  87.  
  88. /* read preferences file */
  89.  
  90. if open(pfile, 'ENV:Scion/ScionRexx.prefs', 'r') then do
  91.   do while ~eof(pfile)
  92.     inln = readln(pfile)
  93.     if inln ~= "" then do
  94.       wstr = upper(word(inln, 1))
  95.  
  96.       select
  97.     when wstr = "USEREQ" then
  98.       usereq = 1
  99.     when wstr = "NOUSEREQ" then
  100.       usereq = 0
  101.     when wstr = "PUBSCREEN" then
  102.       pscr = strip(delstr(inln, 1, length(wstr)), 'b', ' "')
  103.     when wstr = "LINEWIDTH" then
  104.       do
  105.             wstr = word(inln, 2)
  106.             if datatype(wstr, 'w') then plwidth = wstr
  107.       end
  108.     when wstr = "PAGESIZE" then
  109.       do
  110.             wstr = word(inln, 2)
  111.             if datatype(wstr, 'w') then pgsize = wstr
  112.       end
  113.     when wstr = "SUB_N0" then
  114.       subm.0 = delstr(inln, 1, length(wstr)+1)
  115.     when wstr = "SUB_A1" then
  116.       subm.1 = delstr(inln, 1, length(wstr)+1)
  117.     when wstr = "SUB_A2" then
  118.       subm.2 = delstr(inln, 1, length(wstr)+1)
  119.     when wstr = "SUB_A3" then
  120.       subm.3 = delstr(inln, 1, length(wstr)+1)
  121.     when wstr = "SUB_T0" then
  122.       subm.4 = delstr(inln, 1, length(wstr)+1)
  123.     when wstr = "SUB_N1" then
  124.       subm.5 = delstr(inln, 1, length(wstr)+1)
  125.     when wstr = "SUB_N2" then
  126.       subm.6 = delstr(inln, 1, length(wstr)+1)
  127.     when wstr = "SUB_N3" then
  128.       subm.7 = delstr(inln, 1, length(wstr)+1)
  129.     when wstr = "SUB_F0" then
  130.       subf = bittst(b2c(strip(delstr(inln, 1, length(wstr)), 'b')), 1)
  131.     otherwise
  132.       /* unrecognized? skip */
  133.       end
  134.     end
  135.   end
  136.   close(pfile)
  137. end
  138.  
  139. if pscr = "" | (pscr ~= "WORKBENCH" & ~show('p', pscr)) then
  140.   pscr = "SCIONGEN"
  141. scrname = scrname||pscr
  142.  
  143. /* Command line options get priority over global settings */
  144. ParseArguments()
  145.  
  146. if ~show('l','rexxarplib.library') then do
  147.   if exists('libs:rexxarplib.library') then
  148.     call addlib('rexxarplib.library',0,-30,0)
  149. end
  150.  
  151. screentofront(pscr)
  152.  
  153. if usereq & ~show('l','rexxreqtools.library') then do
  154.   if exists('libs:rexxreqtools.library') then
  155.     call addlib('rexxreqtools.library',0,-30,0)
  156.   else do
  157.     usereq = 0; outp = 1
  158.     Tell("Unable to open rexxreqtools.library - using text output")
  159.   end
  160. end
  161.  
  162. /* Originally stolen from Peter Billing - thanks Peter ;-) */
  163. if ~show('P','SCIONGEN') then do
  164.   EndString('I am sorry to say that the SCION Genealogist' || NL ||,
  165.     'database is not available. Please start the' || NL ||,
  166.     'SCION program BEFORE using this script!')
  167. end
  168.  
  169. myport = "SCIONGEN"
  170. address value myport
  171. GETDBNAME
  172. dbname = upper(RESULT)
  173. GETPROGVERSION
  174. progvers = RESULT
  175.  
  176. if progvers >= 4 then do
  177.   GETCURRENTIRN
  178.   irn = RESULT
  179. end
  180.  
  181. if outp & ~usereq then do
  182.   if pscr ~= "WORKBENCH" then do
  183.     scrdev = 'SCNPEDSCR'
  184.     if ~open(scrdev, scrname, 'w') then scrdev = stdout
  185.   end
  186.   Tell("*** PrintPedigree version "||versionstr||" ***")
  187.   Tell("***       by Freddy Ariës      ***")
  188.   Tell("Current database: "||dbname||NL)
  189. end
  190. if prtopt = 0 then do
  191.   /* No use in asking for input if we're not allowed to output anything */
  192.   if usereq then do
  193.     prtopt = rtezrequest('Current Scion database: '||dbname||NL||,
  194.       NL||'Please make your choice: '||,
  195.       NL||'1. Forefathers (male ancestor line only)'||,
  196.       NL||'2. Pedigree Chart; no siblings'||,
  197.       NL||'3. Pedigree Chart; only siblings of proband'||,
  198.       NL||'4. Pedigree Chart; all siblings'||,
  199.       '',' _1 | _2 | _3 | _4 |E_xit','PrintPedigree v'||versionstr||' by Freddy Ariës','rt_pubscrname = '||PSCR)
  200.     if prtopt = 0 then EXIT
  201.  
  202.     if progvers < 4 then do
  203.       irn = rtgetlong(,'Enter the IRN of the person whose'||,
  204.             NL||'ancestors you want to print: '||,
  205.             NL,'Input Request:','_Continue','rt_pubscrname = '||PSCR)
  206.       if irn = '' then EndString("No IRN - aborted.")
  207.       irn = abs(irn)
  208.     end
  209.  
  210.     useirn = rtezrequest('Do you want to output the IRNs'||,
  211.               NL||'(the record numbers) as well?'||,
  212.               '',' _Yes| _No ','Input Request:','rt_pubscrname = '||PSCR)
  213.   end
  214.   else do
  215.     Tell("1. Forefathers (male ancestor line only)")
  216.     Tell("2. Pedigree Chart; no siblings")
  217.     Tell("3. Pedigree Chart; only siblings of proband")
  218.     Tell("4. Pedigree Chart; all siblings")
  219.     TellNN("Your choice: ")
  220.     prtopt = readln(scrdev)
  221.     prtopt = CheckAnswer(word(prtopt,1))
  222.  
  223.     if progvers < 4 then do
  224.       TellNN("Enter the IRN of the person whose ancestors you want to print: ")
  225.       irn = readln(scrdev)
  226.       irn = word(irn, 1)
  227.     end
  228.  
  229.     TellNN("Do you want to output the IRN (numbers) as well (y/n)? ")
  230.     instr = readln(scrdev)
  231.     instr = upper(left(instr, 1))
  232.     Tell("")
  233.     if instr = "Y" then useirn = 1
  234.     else useirn = 0
  235.   end
  236. end
  237.  
  238. if progvers < 4 & ~DATATYPE(irn, 'w') then
  239.   EndString("ERROR: Not a valid IRN: "||irn)
  240.  
  241. EXISTPERSON irn
  242. if RESULT ~= 'YES' then
  243.   EndString("No person with IRN "||irn||" in the current database.")
  244.  
  245. if outp then do
  246.   pname = GetNameStr(irn, 0)
  247.   if usereq then do
  248.     valcont = rtezrequest('The selected person is: '||NL||pname||'.'||,
  249.       NL||'Continue?','_Continue| _Abort','PrintPedigree Request:','rt_pubscrname = '||PSCR)
  250.     if valcont = 0 then EndString("Aborted.")
  251.   end
  252.   else do
  253.     TellNN("Current person is "||pname||". Continue? (y/n) ")
  254.     valcont = readln(scrdev)
  255.     valcont = upper(left(valcont, 1))
  256.     if valcont ~= 'Y' then EndString("Ok.")
  257.   end
  258. end
  259.  
  260. if outp & outname = "" then do
  261.   if usereq then do
  262.     odev = rtezrequest('Current Scion database: '||dbname||,
  263.       NL||'Where should the output be sent to?'||,
  264.       NL,' _File |_Printer|_Screen|_Nowhere','PrintPedigree v'||versionstr||' by Freddy Ariës','rt_pubscrname = '||PSCR)
  265.     select
  266.       when odev = 1 then do
  267.         /* We need a file requester for further data */
  268.         dblen = length(dbname)
  269.         if dblen>6 & right(dbname, 6)=".SCION" then
  270.           dbname=left(dbname, dblen - 6)
  271.         outname = rtfilerequest(,dbname||'.PED','Output filename',,'rtfi_buffer = true   rt_pubscrname = '||PSCR||'   rtfi_initialpath = RAM:',)
  272.         if outname = '' then
  273.           outname = dbname||'.PED'
  274.       end
  275.       when odev = 2 then
  276.         outname = 'PRT:'
  277.       when odev = 3 then
  278.         outname = 'STDOUT'
  279.       otherwise EndString("No output - aborted.")
  280.         /* You selected 'Nowhere' */
  281.     end
  282.   end
  283.   else do
  284.     Tell("Enter output file (filename with complete path, or PRT: for printer,")
  285.     TellNN("or STDOUT for screen): ")
  286.     outname = readln(scrdev)
  287.     outname = strip(outname, 'b', ' "')
  288.     if outname = "" then outname = 'STDOUT'
  289.   end
  290. end
  291.  
  292. /* Anyone know a better way to translate numbers into Roman? */
  293. GenerationS.1 = "I II III IV V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX"
  294. GenerationS.2 = "XXI XXII XXIII XXIV XXV XXVI XXVII XXVIII XXIX XXX XXXI XXXII XXXIII XXXIV XXXV XXXVI XXXVII XXXVIII IXL XL"
  295.  
  296. /* Printer Codes (some of which are currently unused): */
  297. ESC = '1B'x
  298. prtinit = ESC||"#1";     /* ESC#1 initialize      */
  299. prtundon = ESC||"[4m";   /* ESC[4m underline on   */
  300. prtundoff = ESC||"[24m"; /* ESC[24m underline off */
  301. prtdson = ESC||"[1m";    /* ESC[1m boldface on    */
  302. prtdsoff = ESC||"[22m";  /* ESC[22m boldface off  */
  303. prtnlqon = ESC||"[2"||'22'x||"z";  /* ESC[2"z NLQ on  */
  304. prtnlqoff = ESC||"[1"||'22'x||"z"; /* ESC[1"z NLQ off */
  305.  
  306. if ~usereq then
  307.   Tell("Building ancestor table...")
  308.  
  309. currgen = 1; numpers = 1
  310. GENTREE.1 = irn
  311.  
  312. /* Build the ancestor table */
  313. do until ~foundone
  314.   foundone = 0
  315.   currgen = currgen + 1
  316.   numpers = 2 * numpers
  317.   /* = 2 ** (currgen - 1) */
  318.   if currgen <= MaxGens then
  319.   do
  320.     if currgen > DbtGen then
  321.     do
  322.       if usereq then
  323.       do
  324.         docont = rtezrequest('Also parse generation '||currgen||' ?'||,
  325.               NL||'(this may take *very* long!)'||,
  326.               '',' _Yes| _No ','Input Request:','rt_pubscrname = '||PSCR)
  327.       end
  328.       else
  329.       do
  330.         Tell("Also parse generation '||currgen||' ?' (this may take *very* long!)")
  331.         inp = readln(scrdev)
  332.         inp = upper(left(inp, 1))
  333.         Tell("")
  334.         if inp = "Y" then docont = 1
  335.         else docont = 0
  336.       end
  337.     end
  338.     else docont = 1
  339.  
  340.     if docont then
  341.     do
  342.       if prtopt = 1 then
  343.         endnum = numpers+1
  344.         /* no use to build the entire table, if we need only this little */
  345.       else
  346.         endnum = 2*numpers-1
  347.       /*
  348.        * TO DO: at the moment, all the numbers are parsed, even if there
  349.        *  is only one family group with ancestors in this generation
  350.        *  This means that thousands of fields may be checked, to find
  351.        *  two persons. This also makes the program dog slow!
  352.        *  I must find a better method to do this. Suggestions welcome...
  353.        */
  354.       do ct = numpers to endnum by 2
  355.         ct1 = ct % 2
  356.         irn = GENTREE.ct1
  357.         ct1 = ct + 1
  358.         GENTREE.ct = 0
  359.         GENTREE.ct1 = 0
  360.         if irn ~= 0 then do
  361.           GETPARENTS irn
  362.           fgrn = RESULT
  363.           EXISTFAMILY fgrn
  364.           if RESULT = 'YES' then do
  365.             foundone = 1
  366.             GetParentsIRN(fgrn, ct, ct1)
  367.           end
  368.         end
  369.       end
  370.     end
  371.   end
  372.   else do
  373.     if usereq then
  374.       rtezrequest('Maximum number of'||NL||'generations reached.'||NL||,
  375.     NL||'Output truncated','_Continue','PrintPedigree Message:','rt_pubscrname = '||PSCR)
  376.     else
  377.      Tell("Maximum number of generations reached. Output may be truncated.")
  378.   end
  379. end
  380. numgens = currgen - 1
  381.  
  382. /* Now print all the ancestors */
  383. if ~usereq then
  384.   Tell("Printing data...")
  385.  
  386. OpenPrinter()
  387.  
  388. if prtopt = 1 then do
  389.   /* Forefathers; print only male ancestors */
  390.   fill = 7
  391.   np = numpers%2
  392.   if prtrev then
  393.     currgen = currgen - 1
  394.   else
  395.     currgen = 1
  396.   do while np > 1
  397.     g1 = GetGenStr(currgen, fill)
  398.     ct1 = np + 1
  399.     ct2 = np % 2
  400.     /* get the husband's data */
  401.     g1 = g1||GetPersonStr(GENTREE.np)
  402.  
  403.     GETPARENTS GENTREE.ct2
  404.     mf1 = RESULT
  405.     EXISTFAMILY mf1
  406.     if RESULT = 'YES' then
  407.       m1 = GetMarriageStr(mf1)
  408.     else
  409.       m1 = ""
  410.  
  411.     if m1 ~= "" then do
  412.       m1 = g1||", m: "||m1
  413.     end
  414.     else m1 = g1
  415.     g1 = copies(' ',fill)
  416.     PrintLines(m1, fill)
  417.     /* get the wife's data */
  418.     m1 = g1||GetPersonStr(GENTREE.ct1)
  419.     PrintLines(m1, fill)
  420.     PrintLF()  
  421.     if prtrev then
  422.       currgen = currgen - 1
  423.     else
  424.       currgen = currgen + 1
  425.     np = np % 2
  426.   end
  427.   g1 = GetGenStr(currgen, fill)||GetPersonStr(GENTREE.np)
  428.   g1 = g1||GetMarriages(GENTREE.np)
  429.   PrintLines(g1, fill)
  430.   PrintLF()
  431. end
  432. else do
  433.   /* print all */
  434.   if prtrev then
  435.     currgen = currgen - 1
  436.   else
  437.     currgen = 1
  438.   fill = 6
  439.  
  440.   g1 = center("Generation: "||GetGenStr(currgen, fill), plwidth-1)
  441.   PrintLines(g1, fill)
  442.   g1 = "1.    "||GetPersonStr(GENTREE.1)
  443.   g1 = g1||GetMarriages(GENTREE.1)
  444.   PrintLines(g1, fill)
  445.   if prtopt > 2 then
  446.     PrintSiblings(GENTREE.1, 1)
  447.   PrintLF()  
  448.  
  449.   np = 2
  450.   if prtrev then
  451.     currgen = currgen - 1
  452.   else
  453.     currgen = currgen + 1
  454.   do while np < numpers
  455.     g1 = center("Generation: "||GetGenStr(currgen, fill), plwidth)
  456.     PrintLines(g1, fill)
  457.     endnum = 2*np-1
  458.     do ct = np to endnum by 2
  459.       ct1 = ct + 1
  460.       ct2 = ct % 2
  461.       /* print the principal data */
  462.       if GENTREE.ct ~= 0 then do
  463.         g1 = left(ct||".    ",fill)||GetPersonStr(GENTREE.ct)
  464.  
  465.     GETPARENTS GENTREE.ct2
  466.     mf1 = RESULT
  467.     EXISTFAMILY mf1
  468.     if RESULT = 'YES' then
  469.       m1 = GetMarriageStr(mf1)
  470.     else
  471.       m1 = ""
  472.  
  473.         if m1 ~= "" then
  474.     do
  475.           m1 = g1||", m: "||m1
  476.     end
  477.         else m1 = g1
  478.         g1 = copies(' ',fill)
  479.         PrintLines(m1, fill)
  480.         if prtopt = 4 then
  481.           PrintSiblings(GENTREE.ct, ct)
  482.       end
  483.       /* print the spouse data */
  484.       if GENTREE.ct1 ~= 0 then do
  485.         m1 = left(ct1||".    ",fill)||GetPersonStr(GENTREE.ct1)
  486.         PrintLines(m1, fill)
  487.         if prtopt = 4 then
  488.           PrintSiblings(GENTREE.ct1, ct1)
  489.       end
  490.     end
  491.     PrintLF()  
  492.     if prtrev then
  493.       currgen = currgen - 1
  494.     else
  495.       currgen = currgen + 1
  496.     np = np * 2
  497.   end
  498. end
  499. if numgens = 1 then
  500.   PrintLines("No ancestors are recorded for this person.", 0)
  501.  
  502. writech(prtdev, prtnlqoff); /* ESC[1"z NLQ off */
  503. EndString("Done.")
  504.  
  505. EXIT
  506.  
  507. /* Parse command line arguments and set the appropriate global variables */
  508. ParseArguments:
  509. if noirn = "NOIRN" then useirn = 0
  510. else if noirn = "QUIET" || noirn = "NOREQ" then do
  511.   outval = noirn
  512.   noirn = ""
  513. end
  514. else do
  515.   outval = mgen
  516.   mgen = noirn
  517.   noirn = ""
  518. end
  519. if mgen = "QUIET" || mgen = "NOREQ" then do
  520.   outval = mgen
  521.   mgen = ""
  522. end
  523.  
  524. MaxGens = 20
  525. /* due to the Roman numbers, we can't handle more than 40 */
  526. /* but due to speed limitations, I don't advise using more than 20 */
  527. if mgen ~= "" then do
  528.   if DATATYPE(mgen, 'w') & mgen > 0 & mgen < MaxGens then
  529.     MaxGens = mgen
  530. end
  531.  
  532. if outval = "QUIET" then do
  533.   usereq = 0
  534.   outp = 0
  535. end
  536. else if outval = "NOREQ" then
  537.   usereq = 0
  538.  
  539. /* if outname = "" then outname = 'STDOUT' */
  540.  
  541. if prtin = "" then do
  542.   prtopt = 0
  543.   if ~outp then EndString("Requires argument is missing.")
  544.     /* actually, with outp = 0, all it does is EXIT */
  545. end
  546. else do
  547.   prtopt = CheckAnswer(prtin)
  548.   /* Note that it was important to establish outp before calling these */
  549. end  
  550.  
  551. return 0
  552.  
  553. OpenPrinter:
  554. /* Open the printer device and print out a nice header */
  555. if outname = 'STDOUT' then do
  556.   if ~outp | usereq then do /* output screen wasn't opened yet! */
  557.     scrdev = 'SCNPEDSCR'
  558.     if ~open(scrdev, scrname, 'w') then scrdev = stdout
  559.   end
  560.   prtdev = scrdev
  561. end
  562. else do
  563.   prtdev = "PRINTER"
  564.   if ~open(prtdev, outname, 'w') then
  565.     EndString("ERROR: Failed to open output file!")
  566. end
  567. writech(prtdev, prtinit||prtnlqon)
  568. if prtopt = 1 then
  569.   prtstr = "FOREFATHERS (Male ancestor line only)"
  570. else if prtopt = 2 then
  571.   prtstr = "PEDIGREE CHART; No siblings"
  572. else if prtopt = 3 then
  573.   prtstr = "PEDIGREE CHART; Only siblings of proband"
  574. else
  575.   prtstr = "PEDIGREE CHART; All siblings"
  576. prtstr = prtundon||prtdson||prtstr||prtdsoff||prtundoff
  577. DoWrite(prtdev, prtstr)
  578. if subf then do
  579.   if subm.0 ~= "" then DoWrite(prtdev, subm.0)
  580.   if subm.1 ~= "" then DoWrite(prtdev, subm.1)
  581.   if subm.2 ~= "" then DoWrite(prtdev, subm.2)
  582.   if subm.3 ~= "" then DoWrite(prtdev, subm.3)
  583.   if subm.4 ~= "" then DoWrite(prtdev, subm.4)
  584.   if subm.5 ~= "" then DoWrite(prtdev, subm.5)
  585.   if subm.6 ~= "" then DoWrite(prtdev, subm.6)
  586.   if subm.7 ~= "" then DoWrite(prtdev, subm.7)
  587. end
  588. prtstr = prtdson||"Report printed on: "||date()||prtdsoff
  589. DoWrite(prtdev, prtstr)
  590. prtstr = copies('=', plwidth)
  591. DoWrite(prtdev, prtstr)
  592. return 0
  593.  
  594. PrintLines: PROCEDURE EXPOSE prtdev plwidth prtopt pgline pgsize
  595. parse arg ostr, fill
  596. /* TO DO:
  597.  * if there are control strings within ostr (like prtdson or prtdsoff)
  598.  * don't include them in the length count
  599.  */
  600. do while ostr ~= ""
  601.   nnl = plwidth+1
  602.   if length(ostr) > plwidth then do
  603.     do until pc = ' ' | nnl = 1
  604.       pc = substr(ostr, nnl, 1)
  605.       nnl = nnl - 1
  606.     end
  607.     if nnl = 1 then do
  608.       prtstr = left(ostr, plwidth)
  609.       ostr = delstr(ostr, 1, nnl)
  610.     end
  611.     else do
  612.       prtstr = left(ostr, nnl)
  613.       ostr = delstr(ostr, 1, nnl+1)
  614.     end
  615.   end
  616.   else do
  617.     prtstr = ostr
  618.     ostr = ""
  619.   end
  620.   DoWrite(prtdev, prtstr)
  621.   if ostr ~= "" then
  622.     ostr = copies(' ',fill)||ostr
  623. end
  624. return 0
  625.  
  626. PrintLF:
  627. DoWrite(prtdev, "")
  628. return 0
  629.  
  630. PrintSiblings: PROCEDURE EXPOSE prtdev plwidth prtopt useirn pgline pgsize
  631. parse arg inum, prenum
  632. GETPARENTS inum
  633. famfgrn = RESULT
  634. EXISTFAMILY famfgrn
  635. if RESULT ~= 'YES' then return 0; /* no parents, then no siblings */
  636. ix = 0; chnum = 0
  637. do until ischld ~= 'YES'
  638.   GETCHILD famfgrn ix
  639.   prsn = RESULT
  640.   EXISTPERSON prsn
  641.   ischld = RESULT
  642.   if ischld = 'YES' then do
  643.     chnum = chnum + 1
  644.     /* skip a number for person <inum> to indicate where he fits in */
  645.     if prsn ~= inum then do
  646.       ostr = copies(' ',8)||prenum||D2C(chnum+96)". "||GetPersonStr(prsn)
  647.       PrintLines(ostr, 11)
  648.       if chnum = 26 then return 0; /* 'z': can't handle more than 26 children */
  649.     end
  650.   end
  651.   ix = ix + 1
  652. end
  653. return 0
  654.  
  655. GetGenStr: PROCEDURE EXPOSE prtopt GenerationS.
  656. parse arg gnum, fill
  657. if gnum <= 20 then
  658.   gstr = word(GenerationS.1, gnum)
  659. else if gnum <= 40 then
  660.   gstr = word(GenerationS.2, gnum)
  661. else
  662.   return "["||gnum||"]"
  663. if prtopt = 1 then gstr = left(gstr||".     ",fill)
  664. return gstr
  665.  
  666. GetPersonStr: PROCEDURE EXPOSE useirn
  667. parse arg irn
  668. if irn ~= 0 then do
  669.   nstr = GetNameStr(irn)
  670.   nstr = nstr||GetBirthStr(irn)
  671.   nstr = nstr||GetDeathStr(irn)
  672. end
  673. else
  674.   nstr = "UNKNOWN"
  675. return nstr
  676.  
  677. GetNameStr: PROCEDURE EXPOSE useirn
  678. parse arg gnum
  679. /* prtdson = '1B'x||"[1m";    * ESC[1m boldface on    */
  680. /* prtdsoff = '1B'x||"[22m";  * ESC[22m boldface off  */
  681. GETFIRSTNAME gnum
  682. name = RESULT
  683. if name ~= "" then name = name||" "
  684. GETLASTNAME gnum
  685. lname = RESULT
  686. if lname = "" then lname = "UNKNOWN"
  687. name = name||lname
  688. /* another option: name = name||prtdson||lname||prtdsoff
  689.  * Problem: see PrintLines
  690.  */
  691. if useirn then name = name||" ["gnum"]"
  692. return name
  693.  
  694. GetBirthStr: PROCEDURE
  695. parse arg gnum
  696. GETBIRTHPLACE gnum
  697. bstr = RESULT
  698. GETBIRTHDATE gnum
  699. bdat = RESULT
  700. if bdat ~= "" & bstr ~= "" then bstr = bstr||" "
  701. bstr = bstr||bdat
  702. if bstr ~= "" then bstr = ", b: "||bstr
  703. return bstr
  704.  
  705. GetDeathStr: PROCEDURE
  706. parse arg gnum
  707. GETDEATHPLACE gnum
  708. dstr = RESULT
  709. GETDEATHDATE gnum
  710. ddat = RESULT
  711. if ddat ~= "" & dstr ~= "" then dstr = dstr||" "
  712. dstr = dstr||ddat
  713. if dstr ~= "" then dstr = ", d: "||dstr
  714. return dstr
  715.  
  716. GetMarriages: PROCEDURE EXPOSE useirn
  717. parse arg irn
  718. mstr = ""
  719. GETMARRIAGE irn 0
  720. mf = RESULT
  721. EXISTFAMILY mf
  722. if RESULT = 'YES' then do
  723.   mtrue = 1
  724.   GETMARRIAGE irn 1
  725.   m2 = RESULT
  726.   EXISTFAMILY m2
  727.   if RESULT = 'YES' then mset = 1
  728.   else mset = 0
  729. end
  730. else
  731.   mtrue = 0  
  732. mnum = 0
  733. do while mtrue
  734.   m1 = GetMarriageStr(mf)
  735.   if m1 ~= "" then m1  = m1||' '
  736.   ptn = GetPartnerIRN(mf, irn)
  737.   m1 = m1||GetPersonStr(ptn)
  738.  
  739.   mnum = mnum + 1
  740.   if mset then mstr = mstr||", m("||mnum||"): "||m1
  741.   else mstr = mstr||", m: "||m1
  742.  
  743.   GETMARRIAGE irn mnum
  744.   mf = RESULT
  745.   EXISTFAMILY mf
  746.   if RESULT ~= 'YES' then mtrue = 0
  747. end
  748. return mstr
  749.  
  750. GetMarriageStr: PROCEDURE
  751. parse arg mf
  752. GETMARRYPLACE mf
  753. mstr = RESULT
  754. GETMARRYDATE mf
  755. mdat = RESULT
  756. if mdat ~= "" & mstr ~= "" then mstr = mstr||" "
  757. mstr = mstr||mdat
  758. return mstr
  759.  
  760. GetParentsIRN: PROCEDURE EXPOSE GENTREE.
  761. parse arg fnum, ct, ct1
  762. fath = 0; moth = 0
  763. GETSPOUSE fnum
  764. sps = RESULT
  765. EXISTPERSON sps
  766. if RESULT = 'YES' then do
  767.   GETSEX sps
  768.   if RESULT = 'M' then
  769.     fath = sps
  770.   else moth = sps
  771. end
  772. GETPRINCIPAL fnum
  773. prn = RESULT
  774. /* If there are two mothers, or two fathers, then name the principal
  775.  * as 'father' and the spouse as 'mother'
  776.  */
  777. EXISTPERSON prn
  778. if RESULT = 'YES' then do
  779.   GETSEX prn
  780.   if RESULT = 'M' then do
  781.     if fath ~= 0 then
  782.       moth = sps
  783.     fath = prn
  784.   end
  785.   else if moth ~= 0 then
  786.     fath = prn
  787.   else
  788.     moth = prn
  789. end
  790. GENTREE.ct = fath
  791. GENTREE.ct1 = moth
  792. return 0
  793.  
  794. GetPartnerIRN: PROCEDURE
  795. parse arg fnum, inum
  796. GETPRINCIPAL fnum
  797. prn = RESULT
  798. GETSPOUSE fnum
  799. sps = RESULT
  800. if inum = prn then pnum = sps
  801. else if inum = sps then pnum = prn
  802. else pnum = 0
  803. return pnum
  804.  
  805. CheckAnswer: PROCEDURE EXPOSE outp prtdev usereq scrdev
  806. parse arg str
  807. str = left(str, 1)
  808. if ~DATATYPE(str, 'w') | (str < 1 | str > 4) then
  809.   EndString("Invalid option - aborted.")
  810. return  str
  811.  
  812. /*
  813.  * output at most #pgsize lines per page to the print device
  814.  * if pgsize = 0, this feature is turned off (unlimited #lines per page)
  815.  */
  816. DoWrite: PROCEDURE EXPOSE pgline pgsize
  817. parse arg prtdev, ostr
  818. if pgsize ~= 0 & pgline > pgsize then do
  819.   writech(prtdev, '0C'x); /* CTRL-L; next page */
  820.   pgline = 0
  821. end
  822. writeln(prtdev, ostr)
  823. pgline = pgline + 1
  824. return 0
  825.  
  826. Tell: PROCEDURE EXPOSE outp scrdev
  827. parse arg str
  828. if outp then
  829.   writeln(scrdev, str)
  830. return 0
  831.  
  832. TellNN: PROCEDURE EXPOSE outp scrdev
  833. /* Tell, No Newline */
  834. parse arg str
  835. if outp then
  836.   writech(scrdev, str)
  837. return 0
  838.  
  839. EndString: PROCEDURE EXPOSE outp prtdev usereq scrdev pscr
  840. parse arg str
  841. /* If you turned off stdout, no error messages will be shown! */
  842. if usereq then
  843.   rtezrequest(str,'E_xit','PrintPedigree Message:','rt_pubscrname = '||PSCR)
  844. else do
  845.   Tell(str || '0A'x)
  846. end
  847. if outp & ~usereq & (scrdev ~= stdout) then do
  848.   Tell("Press <return> to exit.")
  849.   readln(scrdev)
  850.   close(scrdev)
  851. end
  852. close(prtdev)
  853. EXIT
  854.  
  855. /* Let's make sure you get a nice message when you turn off the printer :-) */
  856.  
  857. IOERR:
  858.   bline = SIGL
  859.   say "I/O error #"||RC||" detected in line "||bline||":"
  860.   say sourceline(bline)
  861.   EXIT
  862.